//
// Copyright (c) 2009-2011, chunquedong
//
// This file is part of ChunMap project
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
//
// History:
//   2011-09-04  Jed Young  Creation
//

using gfx2
using gfx
using chunmapModel
using gfx2Imp
using chunmapData
using web
using concurrent

**
** TileDataSource
**
@Js
@Serializable { simple = true }
const class TileDataSource : RasterDataSource
{
  private const Uri uri
  private const |->|? onLoaded
  private const ImageCache cache
  private const Grid grid
  private const Size size
  private const Float originLevelScale

  new make(Uri uri, |->|? onLoaded := null)
  {
    this.cache = ImageCache.create
    this.uri = uri
    this.onLoaded = onLoaded
    Str metadata := WebClient(uri).getStr
    Str[] metas := metadata.split(';')
    this.grid = Grid(metas[0])
    this.size = Size(metas[1])

    xScale := size.w / grid.width
    yScale := size.h / grid.height
    originLevelScale = xScale.min(yScale)
  }

  override Str toStr() { uri.toStr }
  static TileDataSource fromStr(Str s)
  {
    uri := s.toUri
    |->|? onLoaded := Actor.locals["chunmapTaster.TileDataSource.callback"]
    return TileDataSource(uri, onLoaded)
  }

  private Raster getRaster(CTile tile)
  {
    key := tile.key
    raster := ImageRaster
    {
      it.image = getImage(key)
      it.id = key
      it.envelope = tile.envelope
    }
    return raster
  }

  override Void each(Condition condition, |Feature| f)
  {
    getRasterSet(condition.envelope, condition.scale).each(f)
  }

  private Raster[] getRasterSet(Envelope envelope, Float scale)
  {
    z := Grid.scaleTozoom(scale, originLevelScale)
    list := grid.findTiles(envelope, z)
    r := list.map |CTile tile->Raster|
    {
      getRaster(tile)
    }
    return r
  }

  private Image2? getImage(Str key)
  {
    name := key
    image := cache.get(name)
    if (image != null) return image
    if (cache.contains(name)) return null

    cache.set(name, null)
    uri := `${this.uri}?key=$key`

    Gfx2.setEngine("SWT")
    image = Image2.fromUri(uri)
    {
      cache.set(name, it)
      if(onLoaded != null) onLoaded()
    }
    return null
  }

  override Envelope envelope()
  {
    grid.envelope
  }
}